﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using TimeWar.Engine;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using TimeWar.Engine.Primitives;
using TimeWar.Engine.SceneGraph;
using TimeWar.Shared.Config;
using Microsoft.Xna.Framework.Input;

namespace TimeWar.Demo
{
    public class DemoLevel : Level
    {

        protected KeyboardState currentKeyboardState = new KeyboardState();
        protected GamePadState currentGamePadState = new GamePadState();

        protected KeyboardState previousKeyboardState = new KeyboardState();
        protected GamePadState previousGamePadState = new GamePadState();

        protected float cameraArc = 0;
        protected float cameraRotation = 0;
        protected float cameraDistance = 100;

        protected bool showSpheres;
      

        public DemoLevel(Game game, GraphicsDeviceManager deviceManager)
            : base(game, deviceManager)
        {
            Game.Content.RootDirectory = "Content";

            graphics.MinimumVertexShaderProfile = ShaderProfile.VS_3_0;
            graphics.MinimumPixelShaderProfile = ShaderProfile.PS_3_0;

            defaultCamera = new Camera(CameraType.Chase);
            defaultCamera.setAspectRatio((float)device.Viewport.Width / numOfPlayers, (float)device.Viewport.Height);
            //defaultCamera.setAspectRatio(16f, 9f);

            playerNode = new SceneNode(SceneNodeType.AnimatedCharacter, graphics.GraphicsDevice);
            //node.Position = new Vector3(0, 10, 0);
            playerNode.Scale = 0.00005f;

        }

        protected override void LoadContent()
        {
            
            levelConfigManager = Game.Content.Load<LevelConfig>("Config\\DemoLevel");
            alliedConfigManager = Game.Content.Load<AlliedConfig>("Config\\Allies");

            base.LoadContent();

            playerNode.Scale = (float)alliedConfigManager.Player.Scale;


        }

        public override void Update(GameTime gameTime)
        {

            HandleInput();

            // Read gamepad inputs.
            float headRotation = currentGamePadState.ThumbSticks.Left.X;
            float armRotation = Math.Max(currentGamePadState.ThumbSticks.Left.Y, 0);

            // Read keyboard inputs.
            if (currentKeyboardState.IsKeyDown(Keys.PageUp))
                headRotation = -1;
            else if (currentKeyboardState.IsKeyDown(Keys.PageDown))
                headRotation = 1;

            if (currentKeyboardState.IsKeyDown(Keys.Space))
                armRotation = 0.5f;

            playerNode.setArmRotation(armRotation);
            playerNode.setHeadRotation(headRotation);


            UpdateCamera(gameTime);

            base.Update(gameTime);
        }

        /// <summary>
        /// Handles camera input.
        /// </summary>
        private void UpdateCamera(GameTime gameTime)
        {
            float time = (float)gameTime.ElapsedGameTime.TotalMilliseconds;

            // Check for input to rotate the camera up and down around the model.
            if (currentKeyboardState.IsKeyDown(Keys.Up) ||
                currentKeyboardState.IsKeyDown(Keys.W))
            {
                cameraArc += time * 0.1f;
                defaultCamera.Rotation++;
            }

            if (currentKeyboardState.IsKeyDown(Keys.Down) ||
                currentKeyboardState.IsKeyDown(Keys.S))
            {
                cameraArc -= time * 0.1f;
                defaultCamera.Rotation--;
            }

            cameraArc += currentGamePadState.ThumbSticks.Right.Y * time * 0.25f;

            // Limit the arc movement.
            if (cameraArc > 90.0f)
                cameraArc = 90.0f;
            else if (cameraArc < -90.0f)
                cameraArc = -90.0f;

            // Check for input to rotate the camera around the model.
            if (currentKeyboardState.IsKeyDown(Keys.Right) ||
                currentKeyboardState.IsKeyDown(Keys.D))
            {
                cameraRotation += time * 0.1f;
            }

            if (currentKeyboardState.IsKeyDown(Keys.Left) ||
                currentKeyboardState.IsKeyDown(Keys.A))
            {
                cameraRotation -= time * 0.1f;
            }

            cameraRotation += currentGamePadState.ThumbSticks.Right.X * time * 0.25f;

            // Check for input to zoom camera in and out.
            if (currentKeyboardState.IsKeyDown(Keys.Z))
                cameraDistance += time * 0.25f;

            if (currentKeyboardState.IsKeyDown(Keys.X))
                cameraDistance -= time * 0.25f;

            cameraDistance += currentGamePadState.Triggers.Left * time * 0.5f;
            cameraDistance -= currentGamePadState.Triggers.Right * time * 0.5f;

            // Limit the camera distance.
            if (cameraDistance > 500.0f)
                cameraDistance = 500.0f;
            else if (cameraDistance < 10.0f)
                cameraDistance = 10.0f;

            if (currentGamePadState.Buttons.RightStick == ButtonState.Pressed ||
                currentKeyboardState.IsKeyDown(Keys.R))
            {
                cameraArc = 0;
                cameraRotation = 0;
                cameraDistance = 100;
            }

            defaultCamera.Arc = cameraArc;
            defaultCamera.Distance = cameraDistance;
            defaultCamera.Rotation = cameraRotation;

        }


        public override void Draw(GameTime gameTime)
        {

            base.Draw(gameTime);


            if (playerNode.ShowSpheres)
            {

                graphics.GraphicsDevice.RenderState.FillMode = FillMode.WireFrame;
                playerNode.DrawBoundingSpheres(defaultCamera.View, defaultCamera.Projection);
                graphics.GraphicsDevice.RenderState.FillMode = FillMode.Solid;

            }


        }


        #region Handle Input


        /// <summary>
        /// Handles input for quitting the game.
        /// </summary>
        private void HandleInput()
        {
            previousKeyboardState = currentKeyboardState;
            previousGamePadState = currentGamePadState;

            currentKeyboardState = Keyboard.GetState();
            currentGamePadState = GamePad.GetState(PlayerIndex.One);

            // Check for exit.
            if (currentKeyboardState.IsKeyDown(Keys.Escape) ||
                currentGamePadState.Buttons.Back == ButtonState.Pressed)
            {
                //Exit();
            }

            // Toggle the collision sphere display.
            if ((currentKeyboardState.IsKeyDown(Keys.Enter) &&
                 previousKeyboardState.IsKeyUp(Keys.Enter)) ||
                (currentGamePadState.IsButtonDown(Buttons.A) &&
                 previousGamePadState.IsButtonUp(Buttons.A)))
            {
                showSpheres = !showSpheres;
            }

            playerNode.ShowSpheres = showSpheres;
        }



        #endregion



    }
}
